package io.modifier.basic.compose.hooks.data

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import io.modifier.basic.compose.hooks.comm.GetValueFn
import io.modifier.basic.compose.hooks.comm.SetValueFn
import io.modifier.basic.compose.hooks.comm.SetterEither

/*
  Description: Better `useState`
*/

/**
 *
 * 在 [useState] 上使用解构声明可能会导致关闭问题。使用 [useLatestRef] 是一种解决方案，但如果快速（毫秒级）调用 set 函数，就会出现状态丢失的问题。
 *
 * 现在你可以使用 [useGetState] 来解决这些问题，并通过 'getter' 获取最新的值，以避免闭包问题。'setter' 函数还支持快速更新。
 *
 */
@Composable
fun <T> useGetState(default: T & Any): GetStateHolder<T & Any> {
    val state = useState(default)
    return remember {
        GetStateHolder(
            state = state,
            setValue = { value: SetterEither<T & Any> ->
                val newValue = value.fold({ it }, { it(state.value) })
                state.value = newValue
            },
            getValue = { state.value }
        )
    }
}

/**
 * A nullable version of [useGetState]
 *
 * @param default
 * @param T
 * @return
 */
@Composable
fun <T> _useGetState(default: T): GetStateHolder<T> {
    val state = _useState(default)
    return remember {
        GetStateHolder(
            state = state,
            setValue = { value: SetterEither<T> ->
                val newValue = value.fold({ it }, { it(state.value) })
                state.value = newValue
            },
            getValue = { state.value }
        )
    }
}

@Stable
data class GetStateHolder<T>(
    val state: State<T>,
    val setValue: SetValueFn<SetterEither<T>>,
    val getValue: GetValueFn<T>,
)
